Beier–Neely morphing algorithm
算法原理
主要算法流程如下:
因为有是生成中间帧,所以目标图是每一张中间帧,而原图为输入图像。为避免歧义,将输入图像称为 srcsrc 和 dstdst。
简单地说,对于中间帧的每一个像素 XX ,对于每一条特征线,计算 XX 在 srcsrc 和 dstdst 基于该特征线的映射,然后加权平均算出最终在两图的映射 X′X′。然后使用 Bilinear 插值求出两个 X′X′ 的像素值,再加权平均求得 XX 最终的像素值。
生成中间帧特征线
这里根据帧数计算权重作 srcsrc 和 dstdst 特征线对的插值。设 ss 为特征线的起点,ee 为特征线的终点,则
ratio=i/n,i=1,…,nratio=i/n,i=1,…,n
s′=ssrc⋅(1−ratio)+sdst⋅ratios′=ssrc⋅(1−ratio)+sdst⋅ratio
e′=esrc⋅(1−ratio)+edst⋅ratioe′=esrc⋅(1−ratio)+edst⋅ratio
计算 X′X′
由上图可见,主要是通过 XX 在目标图中相对于特征线(向量)的位置,映射回原图对应特征线相对的位置。这个位置由 XX 在特征线上的投影和距离决定。
u=(X−P)⋅(Q−P)||Q−P||2u=(X−P)⋅(Q−P)||Q−P||2
v=(X−P)⋅Perpendicular(Q−P)||Q−P||v=(X−P)⋅Perpendicular(Q−P)||Q−P||
X′=P′+u⋅(Q′−P′)+v⋅Perpendicular(Q′−P′)||Q′−P′||X′=P′+u⋅(Q′−P′)+v⋅Perpendicular(Q′−P′)||Q′−P′||
X′X′ 的加权平均
通过下面的权重公式计算每一条特征线在当前 XX 中占的权重:
weight=(lengthpa+dis)bweight=(lengthpa+dis)b
其中 a,b,pa,b,p 为参数,我取的是 1,2,01,2,0,即权重与特征线的长度无关。
然后加到一个总的 xsumxsum 和 weightsumweightsum 上
xsum=xsum+X′⋅weightxsum=xsum+X′⋅weight
weightsum=weightsum+weightweightsum=weightsum+weight
当所有特征线都遍历过后,就可以求出最终的 X′
X′=xsum/weightsum
Bilinear
这里是通过映射得到的 X′ 获得对应的 rgb。借用课件的图:
假设绿点为 (x,y),对应的像素值为 S(x,y),则有
S(x,y)=(1−a)⋅(1−b)⋅S(i,j)+a⋅(1−b)⋅S(i+1,j)+(1−a)⋅b⋅S(i,j+1)+a⋅b⋅S(i+1,j+1)
容易看出,这样插值当 (x,y) 为任意一个顶点时,像素值即是该点的值。
像素值加权平均
在求得 src 和 dst 的像素值 s1,s2 后,设当前帧数为 i,总帧数为 n 。则 X 的像素值为
sx=s1⋅(1−in)+s2⋅in,i=1,⋯,n
通过上面的算法步骤即可获得 Morphing 的中间帧。当然,在运行上面算法时还要自己标出特征线。
评论